import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';
import { FormattedMessage } from 'umi/locale';
import {
  Card, Form, Input, Button, Modal, message, Table, Checkbox,
} from 'antd';
import StandardTable from '@/components/StandardTable';
import styles from './role.less';
import Authorized from '@/pages/Authorized';

const FormItem = Form.Item;
const { TextArea } = Input;
const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');

/**
 * 角色列表
 */
@connect(({ permission, menu, loading }) => ({
  permission,
  menu,
  loading,
}))
@Form.create()
class RoleManagement extends PureComponent {
  state = {
    expandForm: false,// 简单/复杂查询条件表单切换boolean
    formValues: {},// 查询条件

    modalVisible: false,// 新增角色Modal可见性
    confirmLoading: false,// 新增角色Modal确认按钮Loading

    updateModalVisible: false,// 修改角色Modal可见性
    updateConfirmLoading: false,// 修改角色Modal确认按钮Loading
    updateFormValues: {},// 修改角色表单数据

    rightSetModalVisible: false,// 指定权限Modal可见性
    rightSetModalLoading: false,// 指定权限Modal内部Loading
    rightSetRoleId: {},// 要指定权限的RoleId
    targetRightIds: [],// 选中权限Id
    rightSetConfirmLoading: false,// 指定权限Modal确认按钮Loading
    indeterminate: true,// 全选框：是否部分选中（样式）
    checkAll: false,// 全选框：是否全选
  };

  columns = [
    {
      title: '序号',
      dataIndex: 'no',
      render: (text, record, index) => <span>{index + 1}</span>,
    },
    {
      title: '角色名称',
      dataIndex: 'name',
    },
    {
      title: '描述',
      dataIndex: 'roleDesc',
    },
    {
      title: '创建日期',
      dataIndex: 'created',
      sorter: true,
      render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>,
    },
    {
      title: '修改日期',
      dataIndex: 'updated',
      sorter: true,
      render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>,
    },
    {
      title: '操作',
      render: (text, record) => (
        <Fragment>
          <Authorized authority={['10403']}>
            <Button type="link" onClick={() => this.handleUpdateModalVisible(true, record)} size='small'>编辑</Button>
          </Authorized>
          <Authorized authority={['10413']}>
            <Button type="link" onClick={() => this.handleRightSetModalVisible(true, record)} size='small'>指定权限</Button>
          </Authorized>
        </Fragment>
      ),
    },
  ];

  // 生命周期方法：组件渲染完成
  componentDidMount() {
    const { dispatch } = this.props;
    // 角色列表数据获取
    dispatch({
      type: 'permission/fetchRole',
    });
    // 权限数据获取
    dispatch({
      type: 'permission/fetchRight',
      payload: { pageSize: 99999 },
    });
  }

  // Table onChange事件：分页、筛选、排序处理
  handleStandardTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const { formValues } = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = { ...obj };
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      currentPage: pagination.current,
      pageSize: pagination.pageSize,
      ...formValues,
      ...filters,
    };
    if (sorter.field) {
      params.sorter = `${sorter.field}_${sorter.order}`;
    }

    dispatch({
      type: 'permission/fetchRole',
      payload: params,
    });
  };

  // 显示新建Modal对话框
  handleModalVisible = flag => {
    this.setState({
      modalVisible: !!flag,
    });
  };

  // 显示修改Modal对话框
  handleUpdateModalVisible = (flag, record) => {
    this.setState({
      updateModalVisible: !!flag,
      updateFormValues: record || {},
    });
  };

  // 显示权限指定Modal对话框
  handleRightSetModalVisible = (flag, record) => {
    // 显示
    if (!!flag && !this.state.rightSetModalVisible) {
      const { loading } = this.props;
      if (loading.effects['permission/fetchRight']) {
        message.warning('请稍后再试...');
        return;
      }
      this.setState({
        rightSetModalVisible: !!flag,
        rightSetModalLoading: true,
        indeterminate: false,// 全选框默认不勾选
        checkAll: false,// 全选框默认不勾选
      });

      const { dispatch, permission: { dataRight }, } = this.props;

      dispatch({
        type: 'permission/fetchRoleRight',
        payload: {
          roleId: record.id,
        },
        callback: (res) => {
          if (res) {
            this.setState({ targetRightIds: res, rightSetRoleId: record.id });
          } else {
            this.setState({ targetRightIds: [], rightSetRoleId: record.id });
          }
          this.setState({
            rightSetModalLoading: false,
            // 判断设置全选框状态
            indeterminate: !!this.state.targetRightIds.length && (this.state.targetRightIds.length < dataRight.list.length),
            checkAll: this.state.targetRightIds.length === dataRight.list.length,
          });
        },
      });
    } else {
      // 隐藏
      this.setState({
        rightSetModalVisible: false,
        targetRightIds: []
      });
    }
  };

  // 新增确认处理
  handleAdd = fields => {
    this.setState({ confirmLoading: true });
    const { dispatch } = this.props;
    dispatch({
      type: 'permission/addRole',
      payload: fields,
      callback: (res) => {
        this.setState({ confirmLoading: false });
        if (res && res.code === 200) {
          this.handleModalVisible();
          message.success('添加成功');
          this.tableReload();
        } else {
          if (res && res.message) {
            message.error(res.message);
          } else {
            message.error('添加失败');
          }
        }
      },
    });
  };

  // 修改确认处理
  handleUpdate = fields => {
    this.setState({ updateConfirmLoading: true });
    const { dispatch } = this.props;
    dispatch({
      type: 'permission/updateRole',
      payload: fields,
      callback: (res) => {
        this.setState({ updateConfirmLoading: false });
        this.handleUpdateModalVisible();
        if (res && res.code === 200) {
          message.success('修改成功');
          this.tableReload();
        } else {
          if (res && res.message) {
            message.error(res.message);
          } else {
            message.error('修改失败');
          }
        }
      },
    });
  };

  // 重新查询
  tableReload = () => {
    const { dispatch } = this.props;
    const { formValues } = this.state;
    dispatch({
      type: 'permission/fetchRole',
      payload: formValues,
    });
  };

  // 权限Checkbox Group选择变化处理
  handleChange = (checkedValues) => {
    // console.log('checked = ', checkedValues);
    const {
      permission: { dataRight },
    } = this.props;
    this.setState({
      targetRightIds: checkedValues,
      // 判断设置全选框状态
      indeterminate: !!checkedValues.length && (checkedValues.length < dataRight.list.length),
      checkAll: checkedValues.length === dataRight.list.length,
    });
  };

  // 全选处理
  handleCheckAllChange = (e) => {
    const {
      permission: { dataRight },
    } = this.props;
    this.setState({
      targetRightIds: e.target.checked ? dataRight.list.map(item => item.id) : [],
      indeterminate: false,
      checkAll: e.target.checked,
    });
  }

  // 指定角色确认处理
  handleRightSet = () => {
    this.setState({ rightSetConfirmLoading: true });
    const { dispatch } = this.props;
    dispatch({
      type: 'permission/setRoleRight',
      payload: {
        roleId: this.state.rightSetRoleId,
        rightIds: this.state.targetRightIds,
      },
      callback: (res) => {
        this.setState({ rightSetConfirmLoading: false });
        this.handleRightSetModalVisible();
        if (res && res.code === 200) {
          message.success('指定权限成功');
        } else {
          if (res && res.message) {
            message.error(res.message);
          } else {
            message.error('指定权限失败');
          }
        }
      },
    });
  };

  // 查询列表 默认渲染
  render() {
    const {
      permission: { dataRole, dataRight },
      menu: { menuData },
      loading,
    } = this.props;
    const { modalVisible, updateModalVisible, updateFormValues,
      confirmLoading, updateConfirmLoading, rightSetConfirmLoading, rightSetModalLoading,
      rightSetModalVisible, targetRightIds,
      indeterminate, checkAll } = this.state;

    const addMethods = {
      handleModalVisible: this.handleModalVisible,
      handleAdd: this.handleAdd,
    };
    const updateMethods = {
      handleUpdateModalVisible: this.handleUpdateModalVisible,
      handleUpdate: this.handleUpdate,
    };
    const rightSetMethods = {
      handleRightSetModalVisible: this.handleRightSetModalVisible,
      handleChange: this.handleChange,
      handleRightSet: this.handleRightSet,
      handleCheckAllChange: this.handleCheckAllChange,
    };
    return (
      <Fragment>
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListOperator}>
              <Authorized authority={['10402']}>
                <Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}><FormattedMessage id="permission.form.btn.create" /></Button>
              </Authorized>
            </div>
            <StandardTable
              rowKey={record => record.id}
              isRowSelect={false}
              selectedRows={[]}
              loading={loading.effects['permission/fetchRole']}
              data={dataRole}
              columns={this.columns}
              onChange={this.handleStandardTableChange}
            />
          </div>
        </Card>
        <CreateForm {...addMethods}
          modalVisible={modalVisible}
          confirmLoading={confirmLoading}
        />
        {updateFormValues && Object.keys(updateFormValues).length ? (
          <UpdateForm {...updateMethods}
            updateModalVisible={updateModalVisible}
            updateConfirmLoading={updateConfirmLoading}
            values={updateFormValues}
          />
        ) : null}
        <RightSetForm {...rightSetMethods}
          rightSetModalVisible={rightSetModalVisible}
          dataMenu={menuData}
          dataRight={dataRight.list}
          targetRightIds={targetRightIds}
          rightSetConfirmLoading={rightSetConfirmLoading}
          rightSetModalLoading={rightSetModalLoading}
          indeterminate={indeterminate}
          checkAll={checkAll}
        />
      </Fragment>
    );
  }
}

// 新建角色Modal
const CreateForm = Form.create()(props => {
  const { modalVisible, form, handleAdd, handleModalVisible, confirmLoading } = props;
  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      handleAdd(fieldsValue);
    });
  };
  return (
    <Modal
      destroyOnClose
      title="新建角色"
      visible={modalVisible}
      onOk={okHandle}
      confirmLoading={confirmLoading}
      onCancel={() => handleModalVisible()}
    >
      <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="角色名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入至少两个字符的角色名称！', min: 2 }],
        })(<Input placeholder="请输入" />)}
      </FormItem>
      <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
        {form.getFieldDecorator('roleDesc', {
          rules: [{ required: true, message: '请输入角色描述！' }],
        })(<TextArea placeholder="请输入" rows={3} style={{ minHeight: 32 }} />)}
      </FormItem>
    </Modal>
  );
});

// 修改角色Modal
const UpdateForm = Form.create()(props => {
  const { updateModalVisible, form, handleUpdate, handleUpdateModalVisible, values, updateConfirmLoading } = props;
  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      handleUpdate(fieldsValue);
    });
  };

  return (
    <Modal
      key={values.id}
      destroyOnClose
      title="编辑角色"
      visible={updateModalVisible}
      onOk={okHandle}
      confirmLoading={updateConfirmLoading}
      onCancel={() => handleUpdateModalVisible(false, values)}
      afterClose={() => handleUpdateModalVisible()}
    >
      {form.getFieldDecorator('id', { initialValue: values.id })(<Input type="hidden" />)}
      <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="角色名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入至少两个字符的角色名！', min: 2 }],
          initialValue: values.name,
        })(<Input placeholder="请输入" />)}
      </FormItem>
      <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
        {form.getFieldDecorator('roleDesc', {
          rules: [{ required: true, message: '请输入角色描述！', min: 1 }],
          initialValue: values.roleDesc,
        })(<TextArea placeholder="请输入" rows={3} style={{ minHeight: 32 }} />)}
      </FormItem>
    </Modal>
  );
});

// 指定权限Modal
const RightSetForm = Form.create()(props => {
  const {
    dataMenu, dataRight, targetRightIds, rightSetModalVisible, rightSetConfirmLoading, rightSetModalLoading,
    handleRightSet, handleRightSetModalVisible, handleChange,
    indeterminate, handleCheckAllChange, checkAll } = props;
  // 各菜单的权限options构造
  let optionsByMenuId = (menuId) => {
    return dataRight.filter(item => item.menuId === menuId).map(item => {
      return { label: item.name, value: item.id };
    });
  };
  let columns = [
    {
      title: '菜单',
      dataIndex: 'name',
      key: 'name',
      width: '20%',
    },
    {
      title: '权限',
      render: (text, record) => (
        <Fragment>
          {optionsByMenuId(record.id) && optionsByMenuId(record.id).length > 0 && optionsByMenuId(record.id).map(item =>
            <Checkbox value={item.value} key={item.value}>{item.label}</Checkbox>
          )}
        </Fragment>
      ),
      width: '80%',
    },
  ];
  const okHandle = () => {
    handleRightSet();
  };
  return (
    <Modal
      destroyOnClose
      title="指定权限"
      visible={rightSetModalVisible}
      onOk={okHandle}
      onCancel={() => handleRightSetModalVisible()}
      okButtonProps={{ disabled: rightSetModalLoading }}
      width={800}
      footer={[
        <Checkbox
          key="checkAll"
          indeterminate={indeterminate}
          onChange={(e) => handleCheckAllChange(e)}
          checked={checkAll}
        >
          全选
        </Checkbox>,
        <Button key="back" onClick={handleRightSetModalVisible}>取消</Button>,
        <Button key="submit" type="primary"
          loading={rightSetConfirmLoading}
          disabled={rightSetModalLoading}
          onClick={okHandle}
        >
          确定
        </Button>,
      ]}
    >
      <Checkbox.Group style={{ width: '100%' }} value={targetRightIds} onChange={handleChange}>
        <Table
          rowKey={record => record.id}
          columns={columns}
          dataSource={dataMenu}
          loading={rightSetModalLoading}
          defaultExpandAllRows={true}// 默认展开全部
          pagination={false}// 不分页
          size="middle"
        />
      </Checkbox.Group>
    </Modal>
  );
});

export default RoleManagement;
